#pragma once

#include "Common.h"
#include "BaseScanGroup.h"
#include <vector>

namespace GPUCC
{
	class StreamScanGroup : public BaseScanGroup
	{
	public:
		StreamScanGroup(unsigned int Size, unsigned int MaxItemSize, KernelHandler& Handler, cl::Program* prog, cl::Context* context, cl::CommandQueue* queue);
		virtual ~StreamScanGroup();

		virtual void Scan();

	protected:
		virtual void AddItemInfo(unsigned int Size);
		virtual void SetScanFinished();

		std::vector<STREAM_BUFFER_INFO> m_StreamInfo;

	private:
		static void CL_CALLBACK hash_calculated(cl_event event, cl_int command_exec_status, void* user_data);
		static void CL_CALLBACK stream_info_read(cl_event event, cl_int command_exec_status, void* user_data);
		static void CL_CALLBACK data_writen(cl_event event, cl_int command_exec_status, void* user_data);
		static void CL_CALLBACK info_writen(cl_event event, cl_int command_exec_status, void* user_data);
		static void CL_CALLBACK hash_read(cl_event event, cl_int command_exec_status, void* user_data);

		void PrepareFirstChunks();
		unsigned int PrepareNextChunks();

		std::vector<unsigned char> m_Chunks;
		std::vector<BUFFER_INFO> m_ChunksInfo;

		cl::Buffer m_DeviceStreamInfo;

		cl::Event m_KernelFinishEvent;
		cl::Event m_CopyStreamInfoFinishEvent;
		cl::Event m_UpdateDataFinishEvent;
		cl::Event m_UpdateInfoFinishEvent;
		cl::Event m_CopyResultFinishEvent;
	};
}